{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "powered-interaction",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n",
      "abc\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "defined \u001b[32mclass\u001b[39m \u001b[36mMonoid\u001b[39m\r\n",
       "\u001b[36mstringMonoid\u001b[39m: \u001b[32mMonoid\u001b[39m[\u001b[32mString\u001b[39m] = ammonite.$sess.cmd4$Helper$$anon$1@67e7191f\r\n",
       "\u001b[36mintMonoid\u001b[39m: \u001b[32mMonoid\u001b[39m[\u001b[32mInt\u001b[39m] = ammonite.$sess.cmd4$Helper$$anon$2@741e6055\r\n",
       "defined \u001b[32mfunction\u001b[39m \u001b[36msum\u001b[39m"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abstract class Monoid[A] {\n",
    "    def add(x:A,y:A):A\n",
    "    def unit:A\n",
    "}\n",
    "\n",
    "implicit val stringMonoid:Monoid[String] = new Monoid[String] {\n",
    "    def add(x:String,y:String):String = x concat y\n",
    "    def unit:String = \"\"\n",
    "}\n",
    "\n",
    "implicit val intMonoid:Monoid[Int] = new Monoid[Int] {\n",
    "    def add(x:Int,y:Int):Int = x + y\n",
    "    def unit:Int = 0\n",
    "}\n",
    "\n",
    "def sum[A](xs:List[A])(implicit m:Monoid[A]):A =\n",
    "    if (xs.isEmpty) m.unit\n",
    "    else m.add(xs.head,sum(xs.tail))\n",
    "\n",
    "\n",
    "println(sum(List(1,2,3)))\n",
    "println(sum(List(\"a\",\"b\",\"c\")))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "difficult-impact",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[32mimport \u001b[39m\u001b[36mscala.language.implicitConversions\u001b[39m"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import scala.language.implicitConversions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "considered-association",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined \u001b[32mfunction\u001b[39m \u001b[36mlist2ordered\u001b[39m"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "implicit def list2ordered[A](x:List[A])(implicit elem2ordered :A => Ordered[A]):Ordered[List[A]] = new Ordered[List[A]]{\n",
    "    def compare (that:List[A]):Int = 1\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "dedicated-discount",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[32mimport \u001b[39m\u001b[36mscala.language.implicitConversions\n",
       "\n",
       "\u001b[39m\r\n",
       "defined \u001b[32mfunction\u001b[39m \u001b[36mint2Integer\u001b[39m"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import scala.language.implicitConversions\n",
    "\n",
    "implicit def int2Integer(x: Int) =\n",
    "  java.lang.Integer.valueOf(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "further-relay",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Scala",
   "language": "scala",
   "name": "scala"
  },
  "language_info": {
   "codemirror_mode": "text/x-scala",
   "file_extension": ".scala",
   "mimetype": "text/x-scala",
   "name": "scala",
   "nbconvert_exporter": "script",
   "version": "2.11.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
